#ifndef __HEAP_TIMER_H__
#define __HEAP_TIMER_H__

#include <chrono>
#include <arpa/inet.h>
#include <time.h>
#include <algorithm>
#include <unordered_map>
#include <cassert>
#include <vector>
#include <functional>

using TimeoutCallBack = std::function<void()>;
using Clock = std::chrono::high_resolution_clock;
using TimeStamp = Clock::time_point;
using MS = std::chrono::microseconds;

struct TimerNode
{
    int id;
    TimeStamp expires;
    TimeoutCallBack cb;
    bool operator<(const TimerNode &t)
    {
        return expires < t.expires;
    }
    bool operator<=(const TimerNode &t)
    {
        return expires <= t.expires;
    }
};

class HeapTimer
{
public:
    HeapTimer() { heap_.reserve(64); }
    ~HeapTimer() { clear(); }

    void add(int id, int timeOut, const TimeoutCallBack &cb);
    void pop();
    void adjust(int id, int newExpires);
    void dowork(int id);
    void clear();

    void tick();
    int GetNextTick();

private:
    bool siftdown_(size_t i, size_t n);
    void siftup_(size_t i);
    void del_(size_t i);
    void SwapNode(size_t i, size_t j);

private:
    std::vector<TimerNode> heap_;
    std::unordered_map<int, size_t> ref_;
};

#endif